home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / fd.arc / FD.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1986-12-30  |  12.5 KB  |  464 lines

  1. PROGRAM  SortedDirectory;
  2.  
  3. { file:  FD.PAS }
  4.  
  5. {**************************************************************}
  6. {                                                              }
  7. { Authored by:   Robert Shaw                                   }
  8. {                5580 North 180th Street                       }
  9. {                Hugo, Minn  55038                             }
  10. {                612-464-1435                                  }
  11. {                                                              }
  12. { This program was written to provide a fast and easily        }
  13. { readable directory utilizing a color display.                }
  14. {                                                              }
  15. { FD will allow directories of any valid path without regard   }
  16. { to which directory is current.                               }
  17. {                                                              }
  18. { Directories greater than 115 entries are paged such that     }
  19. { all entries are truly in sequence on each viewing page.      }
  20. {                                                              }
  21. {**************************************************************}
  22.  
  23.  
  24. {**************************************************************}
  25. { turbo directives                                             }
  26. {**************************************************************}
  27.  
  28. {$C-}
  29. {$U-}
  30. {$R-}
  31. {$K-}
  32. {$V-}
  33.  
  34. {**************************************************************}
  35. { declarations                                                 }
  36. {**************************************************************}
  37.  
  38. TYPE
  39.   String80  = STRING[80];
  40.  
  41.   KeyRec    = RECORD
  42.                 name      : STRING[12];
  43.                 ext       : STRING[4];
  44.                 dirattrib : BOOLEAN;
  45.               END;
  46.  
  47.   FileList  = ARRAY[1..768] OF KeyRec;
  48.  
  49.   Registers = RECORD
  50.                 CASE INTEGER OF
  51.                   1: (AX,BX,CX,DX,BP,SI,DI,DS,ES,FLAGS : INTEGER);
  52.                   2: (AL,AH,BL,BH,CL,CH,DL,DH : BYTE);
  53.                 END;
  54.  
  55. VAR
  56.   reg        : Registers;
  57.   list       : FileList;
  58.   mask       : String[62];
  59.   currentdir : String[62];
  60.   heading    : String80;
  61.   total      : INTEGER;
  62.   mono       : BOOLEAN;
  63.   tempchar   : CHAR;
  64.  
  65.  
  66. {**************************************************************}
  67. { support procedures                                           }
  68. {**************************************************************}
  69.  
  70. PROCEDURE  WriteBrite( text  : String80 );
  71. BEGIN
  72.   TextColor(Yellow);
  73.   Write(text);
  74.   TextColor(Cyan);
  75. END;
  76.  
  77.  
  78.  
  79. PROCEDURE  Bleep(times : BYTE );
  80. VAR
  81.   i : BYTE;
  82. BEGIN
  83.   FOR i := 1 to times DO BEGIN
  84.     Sound(880);
  85.     Delay(60);
  86.     Sound(440);
  87.     Delay(60);
  88.     NoSound;
  89.   END;
  90. END;
  91.  
  92.  
  93.  
  94. PROCEDURE  DisplayError( error : BYTE );
  95. VAR
  96.   prompt : String80;
  97. BEGIN
  98.   CASE error OF
  99.     1 : prompt := 'invalid or none';
  100.     2 : prompt := 'invalid parameters';
  101.   END;
  102.   WriteLn(prompt);
  103.   Bleep(1);
  104.   Halt;
  105. END;
  106.  
  107.  
  108.  
  109. PROCEDURE  StringUpperCase (VAR Strg : String80);
  110.   {convert string to uppercase}
  111. BEGIN
  112.   INLINE
  113.   ($C4/$BE/Strg/                {       LES    DI, Strg[BP]            }
  114.    $26/$8A/$0D/                 {       MOV    CL, ES:DI               }
  115.    $FE/$C1/                     {       INC    CL                      }
  116.    $FE/$C9/                     { L1:   DEC    CL                      }
  117.    $74/$13/                     {       JZ     L2                      }
  118.    $47/                         {       INC    DI                      }
  119.    $26/$80/$3D/$61/             {       CMP    ES:BYTE PTR [DI], 'a'   }
  120.    $72/$F5/                     {       JB     L1                      }
  121.    $26/$80/$3D/$7A/             {       CMP    ES:BYTE PTR [DI], 'z'   }
  122.    $77/$EF/                     {       JA     L1                      }
  123.    $26/$80/$2D/$20/             {       SUB    ES:BYTE PTR [DI], 20H   }
  124.    $EB/$E9);                    {       JMP    SHORT L1                }
  125.                                 { L2:                                  }
  126. END;
  127.  
  128.  
  129.  
  130. PROCEDURE  Print(col    : BYTE     ;
  131.                  row    : BYTE     ;
  132.                  text   : String80 ;
  133.                  attrib : BYTE    );
  134. BEGIN
  135.   IF mono THEN attrib := $07;
  136.   INLINE
  137.     ($1E/$1E/$8A/$86/row/$B3/$50/$F6/$E3/$2B/$DB/$8A/$9E/col/
  138.      $03/$C3/$03/$C0/$8B/$F8/$be/$00/$00/$8A/$BE/attrib/
  139.      $8a/$8e/text/$22/$c9/$74/$3e/$2b/$c0/$8E/$D8/$A0/$49/$04/
  140.      $1F/$2C/$07/$74/$22/$BA/$00/$B8/$8E/$DA/$BA/$DA/$03/$46/
  141.      $8a/$9A/text/$EC/$A8/$01/$75/$FB/$FA/$EC/$A8/$01/$74/$FB/
  142.      $89/$1D/$47/$47/$E2/$Ea/$2A/$C0/$74/$10/$BA/$00/$B0/
  143.      $8E/$DA/$46/$8a/$9A/text/$89/$1D/$47/$47/$E2/$F5/$1F);
  144. END;
  145.  
  146. {**************************************************************}
  147. { sort directory files array                                   }
  148. {**************************************************************}
  149.  
  150. PROCEDURE  SortDirectory;
  151. VAR
  152.   i      : INTEGER;
  153.   j      : INTEGER;
  154.   k      : INTEGER;
  155.   spread : INTEGER;
  156.   temp   : KeyRec;
  157. BEGIN
  158.   spread := total DIV 2;
  159.   WHILE spread > 0 DO BEGIN
  160.     FOR i := spread + 1 TO total DO BEGIN
  161.       j := i - spread;
  162.       WHILE j > 0 DO BEGIN
  163.         k := j + spread;
  164.         IF list[j].name <= list[k].name THEN
  165.           j := 0
  166.         ELSE BEGIN
  167.           temp    := list[j];
  168.           list[j] := list[k];
  169.           list[k] := temp;
  170.         END;
  171.         j := j - spread
  172.       END
  173.     END;
  174.     spread := spread DIV 2;
  175.   END;
  176. END;
  177.  
  178. {**************************************************************}
  179. { search directory                                             }
  180. {**************************************************************}
  181.  
  182. PROCEDURE  ReadDirectory;
  183. CONST
  184.   dta : STRING[44] = '                                            ';
  185.  
  186.  
  187.   PROCEDURE  FillRecord;
  188.   VAR
  189.     dotlocation : BYTE;
  190.   BEGIN
  191.     total := SUCC(total);
  192.     WITH list[total] DO BEGIN
  193.       name := COPY(dta, 31, 12);
  194.       ext  := '';
  195.       dirattrib := ((ORD(dta[22]) AND 16) = 16);
  196.  
  197.       IF NOT dirattrib THEN BEGIN
  198.         dotlocation := POS('.', name);
  199.         IF ( dotlocation > 0 ) THEN BEGIN
  200.           ext := COPY(name, dotlocation, 4);
  201.           name[0] := CHR(dotlocation - 1);
  202.         END;
  203.       END;
  204.     END;
  205.   END;
  206.  
  207.  
  208.  
  209. BEGIN
  210.   total := 0;
  211.   mask[LENGTH(mask)+1] := #00;
  212.  
  213.   reg.AH := $1A;
  214.   reg.DS := SEG(dta);
  215.   reg.DX := OFS(dta) + 1;
  216.   MSDos(reg);
  217.  
  218.   reg.AH := $4E;
  219.   reg.DS := SEG(mask);
  220.   reg.DX := OFS(mask) + 1;
  221.   reg.CX := 23;
  222.   MSDos(reg);
  223.  
  224.   IF (reg.FLAGS AND 1) = 0 THEN BEGIN
  225.  
  226.     FillRecord;
  227.  
  228.     REPEAT
  229.       FillChar(dta[31], 14, #00);
  230.  
  231.       reg.AH := $4F;
  232.       MSDos(reg);
  233.  
  234.       IF ( reg.AX <> 18 ) THEN FillRecord;
  235.  
  236.     UNTIL ODD(reg.FLAGS AND 1);
  237.  
  238.   END ELSE
  239.     DisplayError(1);
  240. END;
  241.  
  242. {**************************************************************}
  243. { display sorted files                                         }
  244. {**************************************************************}
  245.  
  246. PROCEDURE  DisplayDirectory;
  247. VAR
  248.   subtotal  : INTEGER;
  249.   k         : INTEGER;
  250.   span      : BYTE;
  251.   index     : BYTE;
  252.   row       : BYTE;
  253.   pagecount : BYTE;
  254.   page      : BYTE;
  255.   start     : BYTE;
  256.  
  257.  
  258.   PROCEDURE  PrintHeading;
  259.   BEGIN
  260.     ClrScr;
  261.     Print(0,0,heading,Yellow);
  262.     row := 1;
  263.   END;
  264.  
  265.  
  266.   PROCEDURE  PrintRecord(  col : BYTE  ;
  267.                          index : BYTE );
  268.   BEGIN
  269.     WITH list[index] DO BEGIN
  270.       IF dirattrib THEN BEGIN
  271.         Print(col, row, name, White);
  272.         Print(col+8, row, '<DIR>', Green);
  273.       END ELSE BEGIN
  274.         Print(col, row, name, Cyan);
  275.         Print(col+8, row, ext, Brown);
  276.       END;
  277.     END;
  278.   END;
  279.  
  280.  
  281.  
  282. BEGIN
  283.   FOR k := total+1 TO total+6 DO BEGIN
  284.     WITH list[k] DO BEGIN
  285.       name := '';
  286.       ext  := '';
  287.       dirattrib := FALSE;
  288.     END;
  289.   END;
  290.  
  291.   heading := 'Directory:  ' + mask;
  292.   IF POS('\*.*', heading) > 0 THEN
  293.     heading := COPY(heading, 1, POS('\*.*',heading)-1);
  294.  
  295.   IF (total > 115) THEN BEGIN
  296.     start := 1;
  297.     span := 23;
  298.     pagecount := total DIV 115;
  299.     IF (pagecount * 115) <> total THEN pagecount := SUCC(pagecount);
  300.  
  301.     FOR page := 1 TO pagecount DO BEGIN
  302.       PrintHeading;
  303.       FOR index := start TO span+start-1 DO BEGIN
  304.  
  305.         PrintRecord( 0, index);
  306.         PrintRecord(16, index + span);
  307.         PrintRecord(32, index + (span * 2));
  308.         PrintRecord(48, index + (span * 3));
  309.         PrintRecord(64, index + (span * 4));
  310.  
  311.         row := SUCC(row);
  312.       END;
  313.  
  314.       IF row = 24 THEN BEGIN
  315.         Print(0,24,'press any key', White);
  316.         GotoXY(14,25);
  317.         Read(kbd, tempchar);
  318.       END;
  319.  
  320.       start := (page * 115) + 1;
  321.       subtotal := total - (page * 115);
  322.       IF subtotal < 116 THEN BEGIN
  323.         span := subtotal DIV 5;
  324.         IF (span * 5) <> subtotal THEN span := SUCC(span);
  325.       END;
  326.     END;
  327.  
  328.   END ELSE BEGIN
  329.  
  330.     PrintHeading;
  331.  
  332.     span := total DIV 5;
  333.     IF (span * 5) <> total THEN span := SUCC(span);
  334.  
  335.     FOR index := 1 TO span DO BEGIN
  336.  
  337.       PrintRecord( 0, index);
  338.       PrintRecord(16, index + span);
  339.       PrintRecord(32, index + (span * 2));
  340.       PrintRecord(48, index + (span * 3));
  341.       PrintRecord(64, index + (span * 4));
  342.  
  343.       row := SUCC(row);
  344.     END;
  345.   END;
  346.  
  347.   GotoXY(1,row+1);
  348. END;
  349.  
  350. {**************************************************************}
  351. { help display                                                 }
  352. {**************************************************************}
  353.  
  354. PROCEDURE  DisplayHelp;
  355. BEGIN
  356.   ClrScr;
  357.   WriteBrite('FD');
  358.   Write(' - ');
  359.   WriteBrite('F');
  360.   Write('ast ');
  361.   WriteBrite('D');
  362.   WriteLn('irectory            (version 12.29)');
  363.   WriteLn;
  364.   WriteLn('Fast color display of tabulated sorted directory.');
  365.   WriteLn;
  366.   WriteBrite('Usage:');
  367.   WriteLn('   FD [path | /h]');
  368.   WriteLn;
  369.   WriteBrite('Option:');
  370.   WriteLn('  path - any valid path');
  371.   WriteLn('         /h   - display help screen');
  372.   WriteLn;
  373.   WriteLn;
  374.   WriteBrite('Author:');
  375.   WriteLn('  Robert Shaw');
  376.   WriteLn('         5580 North 180th Street');
  377.   WriteLn('         Hugo, MN 55038');
  378.   WriteLn;
  379.   Halt;
  380. END;
  381.  
  382. {**************************************************************}
  383. { parameters and set path                                      }
  384. {**************************************************************}
  385.  
  386. PROCEDURE  ParseParameters;
  387. BEGIN
  388.   IF MEM[$0000:$0449] = $07 THEN mono := TRUE ELSE mono := FALSE;
  389.  
  390.   IF ParamCount > 1 THEN DisplayError(2);
  391.  
  392.   IF ParamStr(1) = '/h' THEN DisplayHelp;
  393.  
  394.   IF ParamCount = 1 THEN mask := ParamStr(1) ELSE mask := '*.*';
  395.  
  396.   IF (POS('..',mask)=(LENGTH(mask)-1)) AND (mask[0]>#1) THEN
  397.     mask := mask + '\';
  398.  
  399.   tempchar := mask[LENGTH(mask)];
  400.  
  401.   IF (tempchar=':') OR (tempchar='\') THEN mask := mask + '*.*';
  402.  
  403.   IF mask[2] <> ':' THEN BEGIN
  404.     reg.AH := $19;
  405.     MSDos(reg);
  406.     mask := CHR(reg.AL+65) + ':' + mask;
  407.   END;
  408.  
  409.   IF mask[3] <> '\' THEN BEGIN
  410.     GetDir(ORD(mask[1])-64, currentdir);
  411.     IF LENGTH(currentdir) <> 3 THEN currentdir := currentdir + '\';
  412.     mask := currentdir + COPY(mask, 3, LENGTH(mask));
  413.   END;
  414.  
  415.   StringUpperCase(mask);
  416. END;
  417.  
  418. {**************************************************************}
  419. { main                                                         }
  420. {**************************************************************}
  421.  
  422. BEGIN
  423.   ParseParameters;
  424.   ReadDirectory;
  425.  
  426.   IF ( list[1].dirattrib ) AND
  427.              ( total = 1 ) THEN BEGIN
  428.     mask := mask + '\*.*';
  429.     ReadDirectory;
  430.   END;
  431.  
  432.   SortDirectory;
  433.   DisplayDirectory;
  434. END.
  435.  
  436. {**************************************************************}
  437. { revision history                                             }
  438. {**************************************************************}
  439.  
  440. 12.29.86 - creation
  441.  
  442.  
  443. {**************************************************************}
  444. { limitations                                                  }
  445. {**************************************************************}
  446.  
  447. - maximum of 768 directory entries, no checking
  448. - displays only filename and extension, size, date
  449.   and time was not in design criteria
  450.  
  451. {**************************************************************}
  452. { future enhancements                                          }
  453. {**************************************************************}
  454.  
  455. - spiffy up parsing of path
  456. - no page option may be nice?
  457.  
  458. {**************************************************************}
  459. { known bugs                                                   }
  460. {**************************************************************}
  461.  
  462. - doesn't restore cursor color upon exit
  463.  
  464.